package com.stalkernet;

import static java.lang.Math.atan2;
import static java.lang.Math.cos;
import static java.lang.Math.pow;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;
import static java.lang.Math.toRadians;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.kakeya.accessyelp.YelpAccessor;

public class YelpSearch extends MapActivity {
    private MapView mapView;
	private MapController mc;
	private List<GeoPoint> gpts = new ArrayList<GeoPoint>();
	private List<String> names = new ArrayList<String>();
	private GeoPoint searchPoint;
    HashMap<String,Location> friends=new HashMap<String,Location>();
    
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	Intent in=this.getIntent();
    	friends=(HashMap<String,Location>)in.getSerializableExtra("friends");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);
        mc = mapView.getController();
        double lat = 40.751017; double lng = -73.992366;
        YelpAccessor ys = new YelpAccessor(lat, lng, "restaurants");
        searchPoint = new GeoPoint(
        		(int) (lat * 1E6),
    			(int) (lng * 1E6));
        for (int i = 0; i < ys.lats.size(); i++) {
        	gpts.add(new GeoPoint(
        			(int) (ys.lats.get(i) * 1E6),
        			(int) (ys.lngs.get(i) * 1E6)));
        	String name = ys.names.get(i) + ": " + ys.stars.get(i) + " out of 5\n";
        	for (int j = 0; j < ys.categories.get(i).size(); j++) {
				name += ys.categories.get(i).get(j) + " ";
			}
        	name += "\n" + String.format("%.2f miles away", calculationByDistance(searchPoint, 
        									gpts.get(gpts.size()-1)));
        	names.add(name);
        }
        
        mc.animateTo(searchPoint);
        mc.setZoom(14);
        
        MapOverlay mapOverlay = new MapOverlay();
        List<Overlay> listOfOverlays = mapView.getOverlays();
        listOfOverlays.clear();
        listOfOverlays.add(mapOverlay);        
        
        mapView.invalidate();

    }

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	class MapOverlay extends Overlay {

	    public boolean draw(Canvas canvas, MapView mapView, 
	    boolean shadow, long when) 
	    {
	        super.draw(canvas, mapView, shadow);                   
	        Point screenPt = new Point();
	        mapView.getProjection().toPixels(searchPoint, screenPt);
	        
	        //---translate the GeoPoint to screen pixels---
	        for (GeoPoint p: gpts) {
		        Point screenPts = new Point();
		        mapView.getProjection().toPixels(p, screenPts);
	
		        //---add the marker---
		        Bitmap bmp = BitmapFactory.decodeResource(
		            getResources(), R.drawable.pushpin);            
		        canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null);
	        }
	        for(String s:friends.keySet())
	        {
	        	Location l=friends.get(s);
	        	GeoPoint p=new GeoPoint((int)(l.getLatitude()*1E6),(int)(l.getLongitude()*1E6));
	        	Point screenPts = new Point();
		        mapView.getProjection().toPixels(p, screenPts);
		        //---add the marker---
		        Bitmap bmp = BitmapFactory.decodeResource(
		            getResources(), R.drawable.androidmarker);            
		        canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null);
	        }
	      //---add the search point marker---
	        Bitmap bmp2 = BitmapFactory.decodeResource(
	            getResources(), R.drawable.pushpin_red);            
	        canvas.drawBitmap(bmp2, screenPt.x, screenPt.y-50, null);
	        return true;
	    }

	    @Override
        public boolean onTouchEvent(MotionEvent event, MapView mapView) 
        {   
            //---when user lifts his finger---
            if (event.getAction() == 1) {                
                GeoPoint p = mapView.getProjection().fromPixels(
                    (int) event.getX(),
                    (int) event.getY());
                double lat = p.getLatitudeE6() / 1E6;
                double lng = p.getLongitudeE6() /1E6;
                double min = 0.1;
                int selectedInd = -1;
                GeoPoint clicked = new GeoPoint(
                		(int) (lat * 1E6),
            			(int) (lng * 1E6));
                for (int i = 0; i < gpts.size(); i++) {
                	double dist = calculationByDistance(clicked, gpts.get(i));
                	if (dist < min) {
                		selectedInd = i;
                		min = dist;
                	}
                }
                if (selectedInd >= 0) {
	                Toast.makeText(getBaseContext(), 
	                        names.get(selectedInd), 
	                        Toast.LENGTH_LONG).show();
	                Intent intent = new Intent(android.content.Intent.ACTION_VIEW, 
	                		Uri.parse("http://maps.google.com/maps?saddr=40.923,-73.906&daddr="+lat+","+lng));
	                		startActivity(intent);
                }
            }                            
            return false;
        }
	}
	
	public static double lldist(double lt1, double lg1, double lt2,
            double lg2) {
		double earthRadius = 3959;
		double lat1 = toRadians(lt1);
		double lat2 = toRadians(lt2);
		double lng1 = toRadians(lg1);
		double lng2 = toRadians(lg2);
		//Apply Haversine formula.
		double dlat = lat2 - lat1;
		double dlng = lng2 - lng1;
		double a = pow(sin(dlat/2.0), 2.0) + cos(lat1) * cos(lat2)
		           * pow(sin(dlng/2.0),2.0);
		double c = 2.0 * atan2(sqrt(a), sqrt(1-a));
		return earthRadius * c;
    }
	
	public double calculationByDistance(GeoPoint StartP, GeoPoint EndP) {
	      double lat1 = StartP.getLatitudeE6()/1E6;
	      double lat2 = EndP.getLatitudeE6()/1E6;
	      double lon1 = StartP.getLongitudeE6()/1E6;
	      double lon2 = EndP.getLongitudeE6()/1E6;
	      return lldist(lat1, lon1, lat2, lon2);
	   } 
	
}